/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include <sstream>
#include <algorithm>


#include "StringUtil.h"

/** Get the file extension */
std::string GetFileExtension( const std::string &str )
{
    StringUtil util( str, '.' );
    std::string ext = "UNKNOWN";
    while ( util.HasNext() ) 
    {
        ext = util.GetNext();
    } 
    return ext;
}


StringUtil::StringUtil(void)
{
}

/** default delimeter is ' ' */
StringUtil::StringUtil(std::string s, char delim)
{
    m_tokens = Parse( s, delim );
}

/** Set a custom delimeter */
StringUtil::StringUtil(std::string s)
{
    m_tokens = Parse( s, ' ');
}

StringUtil::~StringUtil(void)
{
}

/** Parse out the tokens */
type_StringList StringUtil::Parse( std::string &str,  char delim )
{
    type_StringList tokens;
    // initial spot for substr
    int j = 0, i = 0;

    int size = 0;
    // search through the whole string to
    // find tokens
    while(i < str.length() && j < str.length() )
    {
        size = 0;
        // eat white space
        while( str[j] == delim && j < str.length() ) {
            j++;
            if ( j < str.length() )
                i = j;
        }

        // if we find a space
        while( str[i] != delim && i < str.length() )
        { 
            i++;
            size++;
        }
        if ( j <= i-1 )
            // add this token to the stack
            tokens.push_back( str.substr(j, size) );
        if ( j >= str.length() )
            return tokens;
        j = i;
    }
    return tokens;
}





// helper function
bool IsNumber_c( char c )
{
    // a number
    char nums[] = { '0', '1', '2', '3', '4',
                    '5', '6', '7', '8', '9', '.'
    };

    // search the array
    for ( int i = 0; i < 11; i++ )
    {
        // if we have a match
        // it is a number
        if ( c == nums[i] )
            return true;
    }
    return false;
}

/** Check for a number 
    Note very fragile - TODO add a better check for decimals
 */
bool StringUtil::IsNumber( std::string &str )
{
    for ( int i = 0; i < str.length(); i++ )
    {
        if ( !IsNumber_c( str[i] ) )
            return false;
    }
    return true;
}


/** To Unicode wide string */
std::wstring StringUtil::ToWString( const std::string &str )
{
    // Make space for wide string
    wchar_t* buffer = new wchar_t[str.size() + 1];

    // convert ASCII to UNICODE
    mbstowcs( buffer, str.c_str(), str.size() );

    // NULL terminate it
    buffer[str.size()] = 0;

    // Clean memory and return it
    std::wstring wstr = buffer;
    delete [] buffer;

    return wstr;
}

/** To char string */
std::string StringUtil::ToString( const std::wstring &str )
{
    // Allocate mem for the new str
    char* buffer = new char[ str.size() + 1 ];

    // convert from uni to ascii
    wcstombs(buffer, str.c_str(), str.size() );

    // null terminate
    buffer[str.size()] = 0;

    std::string s = buffer;
    delete [] buffer;

    return s;
}

/** To Upper Case */
std::string StringUtil::ToUpper( const std::string &str )
{
    std::string ustr = str;
    std::transform( str.begin(), str.end(), ustr.begin(), toupper );
    return ustr;
}


/** To lower case */
std::string StringUtil::ToLower( const std::string &str )
{
    std::string lstr = str;
    std::transform( str.begin(), str.end(), lstr.begin(), tolower );
    return lstr;
}
